package cn.wizzer.framework.util.param;

import org.nutz.lang.Strings;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Parameter;
import java.lang.reflect.Proxy;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

/**
 * 验证器
 */
public class ParamValid {
    public void valid(Map<Parameter,Object> parameterObjectMap){
        Set<Parameter> parameters = parameterObjectMap.keySet();
        if (parameters.size()>0){
            for (Parameter parameter : parameters) {
                Param4Map param4Map = parameter.getAnnotation(Param4Map.class);
                Object value = parameterObjectMap.get(parameter);
                if (param4Map != null) {
                    if ( param4Map.fields().length>0) {
                        Map mapValue = (Map)value;
                        for (Param param : param4Map.fields()) {
                            String name = param.name();
                            if (name.equals("")) {
                                ParamException.throwNew("the property named 'name' of annotation param in param4map must been not null");
                            }
                            valid(param,mapValue.get(name));
                        }
                    }
                }

                Param param = parameter.getAnnotation(Param.class);
                if (param != null) {
                    if (Strings.isBlank(param.name())){
                        setParamName(param,parameter.getName());
                    }
                    valid(param,value);
                }
            }
        }


    }

    private void setParamName(Param param, String name) {
        try {
            // 获取代理处理器
            InvocationHandler invocationHandler = Proxy.getInvocationHandler(param);
            // 过去私有 memberValues 属性
            Field f = invocationHandler.getClass().getDeclaredField("memberValues");
            f.setAccessible(true);
            // 获取实例的属性map
            Map<String, Object> memberValues = (Map<String, Object>) f.get(invocationHandler);
            // 修改属性值
            memberValues.put("name", name);
        }catch (Exception e){}
    }

    private void valid(Param param, Object value) {
        boolean required = param.required();
        if (required) {
            if (value == null){
                ParamException.throwNew(String.format("the param named '%s' can not been null", param.name()));
            }
        }
        String regex = param.regex();
        if (Strings.isNotBlank(regex)) {
            if (value != null) {
                boolean matches = Pattern.matches(regex, value.toString());
                if (!matches){
                    ParamException.throwNew(String.format("the param named '%s' must match '%s'", param.name(), regex));
                }
            }
        }
        String[] strings = param.notIn();
    }

}
